package com.shopping.jwt;

import io.jsonwebtoken.*;
import io.jsonwebtoken.security.Keys;

import java.nio.charset.StandardCharsets;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

public class JWTTest {
    //生成秘钥(盐)
    private static String secretKet = "jiahzongxueyuan@wxx006.com#huozhexiao==666777888.com";

    //签发:生成一个Token
    public static String createToken() {
        //标头map集合
        Map<String, Object> heardMap = new HashMap<String, Object>() {{
            put("typ", "JWT");
            put("alg", "HS256");//设置签名算法
        }};
        //负载信息map集合
        Map<String, Object> payloadMap = new HashMap<String, Object>() {{
            put("user_id", 93);
            put("user_name", "admin");
            //下方为jwt提供的标准自段
            put("iss", "huozhexiao");//签发人
            put("exp", new Date(System.currentTimeMillis() + (1000 * 60 *60 * 24 *7)));//过期时间
            put("iat", new Date());//签发时间
            put("sub", "JWT测试");//主题
            put("jti", "huozhexiao001");//编号
        }};
        String token = Jwts.builder()//创建一个JWT构建器对象
                .setHeader(heardMap)//设置标头，可以不设置，有默认值
                .setClaims(payloadMap)//设置负载信息
                .signWith(Keys.hmacShaKeyFor(secretKet.getBytes(StandardCharsets.UTF_8))//设置秘钥
                        , SignatureAlgorithm.HS256 //签名算法
                )
                .compact();//生成Token
        ;
        //生成Token
        return token;
    }

    /**
     * 解析Token
     * 解析时，必须提供秘钥和token字符串
     * @param token
     */
    public static void parseToken(String token){
        //解析指定Token并返回数据
        Jws<Claims> claimsJws = Jwts.parserBuilder()//创建一个解析构建器对象
                .setSigningKey(Keys.hmacShaKeyFor(secretKet.getBytes(StandardCharsets.UTF_8)))//设置解析器所使用的秘钥
                .build()//获得Token解析器对象
                .parseClaimsJws(token);
        ;
        System.out.println(claimsJws.getSignature());//获得签名算法
        JwsHeader header = claimsJws.getHeader();//获得标头对象
        System.out.println(header.getAlgorithm());//获得签名算法
        //获得负载数据对象
        Claims claims = claimsJws.getBody();
        System.out.println(claims.getSubject());//主题
        System.out.println(claims.getIssuer());//签发人
        System.out.println(claims.getExpiration());//过期时间
        System.out.println(claims.getIssuedAt());//签发时间
        System.out.println(claims.getId());//编号
        System.out.println(claims.get("user_id",Integer.class));
        System.out.println(claims.get("user_name",String.class));
    }

    public static void main(String[] args) {
        System.out.println(createToken());
        parseToken("eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJKV1TmtYvor5UiLCJ1c2VyX2lkIjo5MywidXNlcl9uYW1lIjoiYWRtaW4iLCJpc3MiOiJodW96aGV4aWFvIiwiZXhwIjoxNjgwNzk5Nzg1LCJpYXQiOjE2ODAxOTQ5ODUsImp0aSI6Imh1b3poZXhpYW8wMDEifQ.eqkixgAhZ8l7EEGXDcZCLYBNAtP80r-0PZZkw5Yc9WI");
    }
}
